<?php

namespace WxWorkSDK\SendMessage\ApplicationMessage;

use WxWorkSDK\Error\Error;
use WxWorkSDK\Http\Http;
use WxWorkSDK\Result;

/**
 * Trait SendTrait
 * @package  WxWorkSDK\SendMessage\ApplicationMessage
 * @author   George
 * @datetime 2019/5/23 16:17
 * @annotation
 */
abstract class SendBase
{
    const URI = "message/send?access_token=";
    /**
     * @var string
     * @annotation
     */
    public $accessToken = '';
    /**
     * @var string
     * @annotation 成员ID列表（消息接收者，多个接收者用‘|’分隔，最多支持1000个）。特殊情况：指定为@all，则向关注该企业应用的全部成员发送
     */
    public $toUser = "";

    /**
     * @var string
     * @annotation 部门ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     */
    public $toParty = "";
    /**
     * @var string
     * @annotation 标签ID列表，多个接收者用‘|’分隔，最多支持100个。当touser为@all时忽略本参数
     */
    public $toTag = "";

    /**
     * @var null
     * @annotation 企业应用的id，整型。
     */
    public $agentId = null;

    /**
     * @var int
     * @annotation
     */
    public $safe = 0;

    /**
     * @var int 表示是否开启重复消息检查，0表示否，1表示是，默认0
     */
    public $enable_duplicate_check = 0;

    /**
     * @var int 表示是否重复消息检查的时间间隔，默认1800s，最大不超过4小时
     */
    public $duplicate_check_interval = 1800;

    /**
     * @return array
     * @annotation
     */
    abstract public function buildParam(): array;

    /**
     * @return string
     * @annotation 按照规则自定义人数据检测
     */
    abstract public function customCheck(): string;

    /**
     * @param $response
     * @return mixed
     * @annotation
     */
    private function respond($response)
    {
        $response = json_decode($response, true);
        if ($response['errcode'] == 0) {
            return new Result(true, 0, 'ok', $response);
        } else {
            return new Result(false, Error::WX_MISTAKE, $response['errcode'].':'.$response['errmsg']);
        }
    }

    /**
     * @return string
     */
    public function check(): string
    {
        if (empty($this->accessToken)) {
            return Error::NOT_TOKEN_MSG;
        }
        if (empty($this->toUser) && empty($this->toParty) && empty($this->toTag)) {
            return Error::NOT_USER_MSG;
        }
        if (!$this->agentId) {
            return Error::NOT_AGENT_ID_MSG;
        }
        if ($result = $this->customCheck()) {
            return $result;
        }
        return '';
    }

    /**
     * @return Result
     * @annotation
     */
    public function send(): Result
    {
        if ($result = $this->check()) {
            return new Result(false, Error::PARAM_MISTAKE, $result);
        }
        list($bool, $response) = Http::request('POST', self::URI.$this->accessToken, ['json' => $this->buildParam()]);
        if ($bool) {
            return $this->respond($response);
        } else {
            return $response;
        }
    }
}